<template>
  <div class="app-container">
    <div class="txz-editor">
      <!-- 顶部工具栏 -->
      <div class="editor-toolbar">
        <el-button @click="handlePrevious">
          <el-icon><Back /></el-icon>返回
        </el-button>
        <el-button @click="handleUndo" :disabled="!editor.computedState?.canUndo">
          <el-icon><RefreshLeft /></el-icon>撤销
        </el-button>
        <el-button @click="handleRedo" :disabled="!editor.computedState?.canRedo">
          <el-icon><RefreshRight /></el-icon>重做
        </el-button>

        <el-divider direction="vertical" />

        <el-button @click="handlePreview">
          <el-icon><View /></el-icon>预览
        </el-button>

        <el-button @click="handleSave">
          <el-icon><Document /></el-icon>保存
        </el-button>

        <el-button @click="handleClear">
          <el-icon><Delete /></el-icon>清空
        </el-button>

        <el-divider direction="vertical" />

        <el-button @click="handleImport">
          <el-icon><Upload /></el-icon>导入
        </el-button>

        <el-button @click="handleExport">
          <el-icon><Download /></el-icon>导出
        </el-button>
      </div>

      <!-- 编辑区域 -->
      <div class="editor-content">
        <!-- 左侧组件列表 -->
        <div class="component-list">
          <div class="component-category" v-for="(components, category) in categorizedComponents" :key="category">
            <div class="category-divider">
              <span>{{ getCategoryName(category) }}</span>
            </div>
            <div class="component-grid">
              <div
                v-for="component in components"
                :key="component.type"
                class="component-item"
                @click="handleAddComponent(component.type, component.name)"
              >
                <div class="component-icon">
                  <el-icon :size="18">
                    <component :is="getIconComponent(component.icon)" />
                  </el-icon>
                </div>
                <div class="component-name">{{ component.name }}</div>
              </div>
            </div>
          </div>
        </div>

        <!-- 中间预览区 -->
        <div class="preview-area" ref="previewAreaRef">
          <div class="preview-container" ref="previewContainerRef">
            <!-- 同步滚动容器 -->
            <div class="sync-scroll-container" ref="syncScrollRef">
              <div class="phone-and-labels">
                <!-- 手机模拟器 -->
                <div class="phone-container" ref="phoneContainerRef">
                  <div class="phone-header">
                    <div class="phone-notch"></div>
                  </div>
                  <div class="phone-screen">
                    <div
                      class="page-content"
                      :style="{
                        backgroundColor: editor.state.pageConfig.backgroundColor,
                        backgroundImage: editor.state.pageConfig.backgroundImage ? `url(${editor.state.pageConfig.backgroundImage})` : 'none'
                      }"
                      ref="pageContentRef"
                      @scroll="handlePageScroll"
                    >
                      <!-- 渲染组件 -->
                      <div
                        v-for="(component, index) in editor.state.components"
                        :key="component.id"
                        class="component-wrapper"
                        :class="{
                          'component-selected': editor.state.selectedComponentIndex === index
                        }"
                        @click="handleSelectComponent(index)"
                        :ref="(el) => componentRefs[index] = el"
                      >
                        <component
                          v-if="getComponentType(component.type)"
                          :is="getComponentType(component.type)"
                          :data="component.data"
                          :styles="component.styles"
                        />     
                      </div>
                    </div>
                  </div>
                  <div class="phone-footer"></div>          
                </div>
              </div>
            </div>
          </div>

          <!-- 1. 临时占位标签：组件渲染前先显示 -->
          <div
            v-if="isTempLabelShow"
            class="deles"
            :style="tempLabelStyle"
            @click.stop="handleDeleteComponent(tempLabelTargetIndex)"
          >
            <span class="triangle-left"></span>
            <span class="label-text">{{ tempLabelComponentName || '组件' }}</span>
            <i class="el-icon-delete-solid delete-icon" />
          </div>

          <!-- 2. 正式标签：显示所有组件的标签 -->
          <div
            v-for="(component, index) in editor.state.components"
            :key="component.id"
            v-if="editor.state.components.length > 0 && !isTempLabelShow"
            class="deles"
            :style="componentLabelPositions[index] || {}"
            ref="componentLabels"
          >
            <span class="triangle-left"></span>
            <span class="label-text">{{ component.name || COMPONENT_META[component.type]?.name || '组件' }}</span>
            
            <!-- 向上移动按钮 -->
            <div 
              class="move-up-btn" 
              v-if="index > 0"
              @click.stop="handleMoveUpLayer(index)"
              title="向上移动"
            >
              <i class="el-icon-caret-top"></i>
            </div>
            
            <!-- 向下移动按钮 -->
            <div 
              class="move-down-btn" 
              v-if="index < editor.state.components.length - 1"
              @click.stop="handleMoveDownLayer(index)"
              title="向下移动"
            >
              <i class="el-icon-caret-bottom"></i>
            </div>
            
            <!-- 删除按钮 -->
            <i class="el-icon-delete-solid delete-icon" @click.stop="handleDeleteComponent(index)" />
          </div>
          
          <!-- 3. 选中组件时显示的删除按钮 -->
          <div
            v-if="editor.state.selectedComponentIndex !== null && editor.state.components.length > 0"
            class="selected-delete-btn"
            :style="selectedDeleteBtnPosition"
            @click.stop="handleDeleteComponent(editor.state.selectedComponentIndex)"
            title="删除选中组件"
          >
            <i class="el-icon-remove"></i>
          </div>
        </div>

        <!-- 右侧属性面板 -->
        <div class="property-panel">
          <el-tabs v-model="activePropertyTab">
            <el-tab-pane label="页面设置" name="page">
              <PageConfigPanel
                :page-config="editor.state.pageConfig"
                @update="handleUpdatePageConfig"
              />
            </el-tab-pane>

            <el-tab-pane label="组件属性" name="component">
              <div v-if="editor.state.selectedComponentIndex >= 0 && editor.state.selectedComponent">
                <div class="component-info">
                  <h3>{{ editor.state.selectedComponent.name || '未命名组件' }}</h3>
                </div>
                <div v-if="!getPropertyPanelType(editor.state.selectedComponent.type)" class="no-property-panel">
                  <el-empty description="该组件暂无可配置属性" />
                </div>
                <div v-else>
                  <component
                    :is="getPropertyPanelType(editor.state.selectedComponent.type)"
                    :data="editor.state.selectedComponent.data"
                    :styles="editor.state.selectedComponent.styles"
                    @update-data="handleUpdateComponentData"
                    @update-styles="handleUpdateComponentStyles"
                  />
                </div>
              </div>
              <div v-else class="no-property-panel">
                <el-empty description="请选择一个组件" />
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>

      <!-- 预览对话框 -->
      <el-dialog
        v-model="previewVisible"
        title="页面预览"
        width="80%"
        top="5vh"
        destroy-on-close
      >
        <div class="preview-container">
          <div class="phone-container">
            <div class="phone-header">
              <div class="phone-notch"></div>
            </div>
            <div class="phone-screen">
              <div
                class="page-content"
                :style="{
                  backgroundColor: editor.state.pageConfig.backgroundColor,
                  backgroundImage: editor.state.pageConfig.backgroundImage ? `url(${editor.state.pageConfig.backgroundImage})` : 'none'
                }"
              >
                <component
                  v-for="(component, index) in editor.state.components"
                  :key="component.id"
                  :is="getComponentType(component.type)"
                  :data="component.data"
                  :styles="component.styles"
                />
              </div>
            </div>
            <div class="phone-footer"></div>
          </div>
        </div>
      </el-dialog>

      <!-- 导入对话框 -->
      <el-dialog
        v-model="importVisible"
        title="导入页面"
        width="50%"
        destroy-on-close
      >
        <el-form>
          <el-form-item label="选择文件">
            <el-upload
              ref="uploadRef"
              :auto-upload="false"
              :on-change="handleFileChange"
              :limit="1"
              accept=".json"
            >
              <el-button type="primary">选择文件</el-button>
              <template #tip>
                <div class="el-upload__tip">
                  只能上传JSON文件，且不超过10MB
                </div>
              </template>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="importVisible = false">取消</el-button>
            <el-button type="primary" @click="confirmImport">确认导入</el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  RefreshLeft,
  RefreshRight,
  View,
  Document,
  Delete,
  Upload,
  Download,
  Search,
  Picture,
  EditPen,
  Goods,
  Menu,
  Ticket,
  Timer,
  User,
  Wallet,
  Back
} from '@element-plus/icons-vue'

// 导入编辑器核心和组件
import { createDiyEditor } from '@/components/diy/shared/editor-core.js'
import { COMPONENT_TYPES, COMPONENT_CATEGORIES, COMPONENT_META } from '@/components/diy/shared/constants.js'
import SearchBlock from '@/components/diy/vue3/components/SearchBlock.vue'
import ImageBanner from '@/components/diy/vue3/components/ImageBanner.vue'
import TitleText from '@/components/diy/vue3/components/TitleText.vue'
import GoodsCard from '@/components/diy/vue3/components/GoodsCard.vue'
import GoodsList from '@/components/diy/vue3/components/GoodsList.vue'
import MenuGrid from '@/components/diy/vue3/components/MenuGrid.vue'
import MenuList from '@/components/diy/vue3/components/MenuList.vue'
import CouponCard from '@/components/diy/vue3/components/CouponCard.vue'
import SeckillBlock from '@/components/diy/vue3/components/SeckillBlock.vue'
import GrouponBlock from '@/components/diy/vue3/components/GrouponBlock.vue'
import UserCard from '@/components/diy/vue3/components/UserCard.vue'
import UserWallet from '@/components/diy/vue3/components/UserWallet.vue'
import UserCoupon from '@/components/diy/vue3/components/UserCoupon.vue'
import Notice from '@/components/diy/vue3/components/Notice.vue'
import RichText from '@/components/diy/vue3/components/RichText.vue'
import Video from '@/components/diy/vue3/components/Video.vue'
import GraphicNavigation from '@/components/diy/vue3/components/GraphicNavigation.vue'
import TabBar from '@/components/diy/vue3/components/TabBar.vue'
import MagicCube from '@/components/diy/vue3/components/MagicCube.vue'
import AuxiliarySegmentation from '@/components/diy/vue3/components/AuxiliarySegmentation.vue'
import StoreInformation from '@/components/diy/vue3/components/StoreInformation.vue'
import Follow from '@/components/diy/vue3/components/Follow.vue'
import Suspension from '@/components/diy/vue3/components/Suspension.vue'
import OnlineService from '@/components/diy/vue3/components/OnlineService.vue'

// 导入属性面板
import PageConfigPanel from '@/components/diy/vue3/properties/PageConfigPanel.vue'
import SearchBlockPanel from '@/components/diy/vue3/properties/SearchBlockPanel.vue'
import ImageBannerPanel from '@/components/diy/vue3/properties/ImageBannerPanel.vue'
import TitleTextPanel from '@/components/diy/vue3/properties/TitleTextPanel.vue'
import GoodsCardPanel from '@/components/diy/vue3/properties/GoodsCardPanel.vue'
import GoodsListPanel from '@/components/diy/vue3/properties/GoodsListPanel.vue'
import MenuGridPanel from '@/components/diy/vue3/properties/MenuGridPanel.vue'
import MenuListPanel from '@/components/diy/vue3/properties/MenuListPanel.vue'
import CouponCardPanel from '@/components/diy/vue3/properties/CouponCardPanel.vue'
import SeckillBlockPanel from '@/components/diy/vue3/properties/SeckillBlockPanel.vue'
import GrouponBlockPanel from '@/components/diy/vue3/properties/GrouponBlockPanel.vue'
import UserCardPanel from '@/components/diy/vue3/properties/UserCardPanel.vue'
import UserWalletPanel from '@/components/diy/vue3/properties/UserWalletPanel.vue'
import UserCouponPanel from '@/components/diy/vue3/properties/UserCouponPanel.vue'
import NoticePanel from '@/components/diy/vue3/properties/NoticePanel.vue'
import RichTextPanel from '@/components/diy/vue3/properties/RichTextPanel.vue'
import VideoPanel from '@/components/diy/vue3/properties/VideoPanel.vue'
import GraphicNavigationPanel from '@/components/diy/vue3/properties/GraphicNavigationPanel.vue'
import TabBarPanel from '@/components/diy/vue3/properties/TabBarPanel.vue'
import MagicCubePanel from '@/components/diy/vue3/properties/MagicCubePanel.vue'
import AuxiliarySegmentationPanel from '@/components/diy/vue3/properties/AuxiliarySegmentationPanel.vue'
import StoreInformationPanel from '@/components/diy/vue3/properties/StoreInformationPanel.vue'
import FollowPanel from '@/components/diy/vue3/properties/FollowPanel.vue'
import SuspensionPanel from '@/components/diy/vue3/properties/SuspensionPanel.vue'
import OnlineServicePanel from '@/components/diy/vue3/properties/OnlineServicePanel.vue'

// 组件映射
const componentMap = {
  [COMPONENT_TYPES.SEARCH_BLOCK]: SearchBlock,
  [COMPONENT_TYPES.IMAGE_BANNER]: ImageBanner,
  [COMPONENT_TYPES.TITLE_TEXT]: TitleText,
  [COMPONENT_TYPES.GOODS_CARD]: GoodsCard,
  [COMPONENT_TYPES.GOODS_LIST]: GoodsList,
  [COMPONENT_TYPES.MENU_GRID]: MenuGrid,
  [COMPONENT_TYPES.MENU_LIST]: MenuList,
  [COMPONENT_TYPES.COUPON_CARD]: CouponCard,
  [COMPONENT_TYPES.SECKILL_BLOCK]: SeckillBlock,
  [COMPONENT_TYPES.GROUPON_BLOCK]: GrouponBlock,
  [COMPONENT_TYPES.USER_CARD]: UserCard,
  [COMPONENT_TYPES.USER_WALLET]: UserWallet,
  [COMPONENT_TYPES.USER_COUPON]: UserCoupon,
  [COMPONENT_TYPES.NOTICE]: Notice,
  [COMPONENT_TYPES.RICH_TEXT]: RichText,
  [COMPONENT_TYPES.VIDEO]: Video,
  [COMPONENT_TYPES.GRAPHIC_NAVIGATION]: GraphicNavigation,
  [COMPONENT_TYPES.TAB_BAR]: TabBar,
  [COMPONENT_TYPES.MAGIC_CUBE]: MagicCube,
  [COMPONENT_TYPES.AUXILIARY_SEGMENTATION]: AuxiliarySegmentation,
  [COMPONENT_TYPES.STORE_INFORMATION]: StoreInformation,
  [COMPONENT_TYPES.FOLLOW]: Follow,
  [COMPONENT_TYPES.SUSPENSION]: Suspension,
  [COMPONENT_TYPES.ONLINE_SERVICE]: OnlineService
}

const propertyPanelMap = {
  [COMPONENT_TYPES.SEARCH_BLOCK]: SearchBlockPanel,
  [COMPONENT_TYPES.IMAGE_BANNER]: ImageBannerPanel,
  [COMPONENT_TYPES.TITLE_TEXT]: TitleTextPanel,
  [COMPONENT_TYPES.GOODS_CARD]: GoodsCardPanel,
  [COMPONENT_TYPES.GOODS_LIST]: GoodsListPanel,
  [COMPONENT_TYPES.MENU_GRID]: MenuGridPanel,
  [COMPONENT_TYPES.MENU_LIST]: MenuListPanel,
  [COMPONENT_TYPES.COUPON_CARD]: CouponCardPanel,
  [COMPONENT_TYPES.SECKILL_BLOCK]: SeckillBlockPanel,
  [COMPONENT_TYPES.GROUPON_BLOCK]: GrouponBlockPanel,
  [COMPONENT_TYPES.USER_CARD]: UserCardPanel,
  [COMPONENT_TYPES.USER_WALLET]: UserWalletPanel,
  [COMPONENT_TYPES.USER_COUPON]: UserCouponPanel,
  [COMPONENT_TYPES.NOTICE]: NoticePanel,
  [COMPONENT_TYPES.RICH_TEXT]: RichTextPanel,
  [COMPONENT_TYPES.VIDEO]: VideoPanel,
  [COMPONENT_TYPES.GRAPHIC_NAVIGATION]: GraphicNavigationPanel,
  [COMPONENT_TYPES.TAB_BAR]: TabBarPanel,
  [COMPONENT_TYPES.MAGIC_CUBE]: MagicCubePanel,
  [COMPONENT_TYPES.AUXILIARY_SEGMENTATION]: AuxiliarySegmentationPanel,
  [COMPONENT_TYPES.STORE_INFORMATION]: StoreInformationPanel,
  [COMPONENT_TYPES.FOLLOW]: FollowPanel,
  [COMPONENT_TYPES.SUSPENSION]: SuspensionPanel,
  [COMPONENT_TYPES.ONLINE_SERVICE]: OnlineServicePanel
}

const iconMap = {
  'search': Search,
  'picture': Picture,
  'title': EditPen,
  'goods': Goods,
  'menu-grid': Menu,
  'menu-list': Menu,
  'coupon': Ticket,
  'seckill': Timer,
  'groupon': Timer,
  'user': User,
  'wallet': Wallet
}

const categoryNameMap = {
  [COMPONENT_CATEGORIES.BASIC]: '基础组件',
  [COMPONENT_CATEGORIES.GOODS]: '商品组件',
  [COMPONENT_CATEGORIES.MARKETING]: '营销组件',
  [COMPONENT_CATEGORIES.USER]: '用户组件'
}

// 编辑器实例
const editor = createDiyEditor({
  pageTitle: 'DIY页面',
  backgroundColor: '#ffffff'
})

// 响应式数据
const activeCategory = ref(COMPONENT_CATEGORIES.BASIC)
const activePropertyTab = ref('page')
const previewVisible = ref(false)
const importVisible = ref(false)
const importFile = ref(null)
const uploadRef = ref(null)
const dragIndex = ref(-1)
const dropPosition = ref(-1)
const offsetY = ref(0)
const componentRefs = ref([])
const componentLabels = ref([])
const pageContentRef = ref(null)
const syncScrollRef = ref(null)
const lastScrollTop = ref(0)
const previewAreaRef = ref(null)
const previewContainerRef = ref(null)
const phoneContainerRef = ref(null)
const componentLabelStyle = ref({})
const activeComponent = ref(null)
// 临时标签状态
const isTempLabelShow = ref(false)
const tempLabelStyle = ref({})
const tempLabelTargetIndex = ref(-1)
const tempLabelComponentName = ref('')

// 计算组件标签位置
const componentLabelPositions = computed(() => {
  const positions = {}
  if (editor.state.components.length > 0 && phoneContainerRef.value && previewAreaRef.value) {
    // 获取手机容器和预览区域的位置信息
    const phoneContainerRect = phoneContainerRef.value.getBoundingClientRect()
    const previewAreaRect = previewAreaRef.value.getBoundingClientRect()
    
    // 计算标签左侧位置（手机容器右侧）
    const labelLeft = phoneContainerRect.right - previewAreaRect.left + 10
    
    // 获取预览区域的滚动偏移量
    const previewAreaScrollTop = previewAreaRef.value.scrollTop || 0
    
    for (let i = 0; i < editor.state.components.length; i++) {
      if (componentRefs.value[i]) {
        const componentEl = componentRefs.value[i]
        const componentRect = componentEl.getBoundingClientRect()
        
        // 计算标签顶部位置（组件中间位置）- 考虑滚动偏移量
        const labelTop = componentRect.top - previewAreaRect.top + componentRect.height / 2 + previewAreaScrollTop
        
        positions[i] = {
          left: `${labelLeft}px`,
          top: `${labelTop}px`,
          transform: 'translateY(-50%)',
          display: 'flex',
          transition: 'all 0.1s ease',
          //zIndex: editor.state.selectedComponentIndex === i ? 10000 : 9999,
          backgroundColor: editor.state.selectedComponentIndex === i ? '#409eff' : '#909399'
        }
      }
    }
  }
  return positions
})

// 计算选中组件删除按钮的位置
const selectedDeleteBtnPosition = computed(() => {
  if (editor.state.selectedComponentIndex === null || 
      !componentRefs.value[editor.state.selectedComponentIndex] ||
      !phoneContainerRef.value || 
      !previewAreaRef.value) {
    return { display: 'none' }
  }
  
  const selectedIndex = editor.state.selectedComponentIndex
  const componentEl = componentRefs.value[selectedIndex]
  const componentRect = componentEl.getBoundingClientRect()
  
  const phoneContainerRect = phoneContainerRef.value.getBoundingClientRect()
  const previewAreaRect = previewAreaRef.value.getBoundingClientRect()
  
  // 获取预览区域的滚动偏移量
  const previewAreaScrollTop = previewAreaRef.value.scrollTop || 0
  
  // 计算删除按钮位置（组件右上角）
  const btnLeft = phoneContainerRect.right - previewAreaRect.left - 10
  const btnTop = componentRect.top - previewAreaRect.top + previewAreaScrollTop - 12
  
  return {
    left: `${btnLeft}px`,
    top: `${btnTop}px`,
    display: 'flex'
  }
})

// 计算属性
const categorizedComponents = computed(() => {
  const result = {}
  Object.values(COMPONENT_CATEGORIES).forEach(category => {
    result[category] = []
  })
  Object.entries(COMPONENT_META).forEach(([type, meta]) => {
    if (result[meta.category]) {
      result[meta.category].push({ ...meta, type })
    }
  })
  return result
})

// 方法
function getComponentType(type) {
  return componentMap[type] || null
}

function getPropertyPanelType(type) {
  return propertyPanelMap[type] || null
}

function getIconComponent(iconName) {
  return iconMap[iconName] || Document
}

function getCategoryName(category) {
  return categoryNameMap[category] || category
}

// 计算单个组件标签位置
function getComponentLabelStyle(index) {
  if (index === -1 || !componentRefs.value[index] || !phoneContainerRef.value) {
    return {}
  }

  try {
    const componentEl = componentRefs.value[index]
    if (!componentEl) return {}

    const componentRect = componentEl.getBoundingClientRect()
    const phoneContainerRect = phoneContainerRef.value.getBoundingClientRect()
    const previewAreaRect = previewAreaRef.value.getBoundingClientRect()
    const pageContentRect = pageContentRef.value.getBoundingClientRect()
    
    // 计算组件相对于页面内容的位置
    const relativeToPageTop = componentRect.top - pageContentRect.top
    
    // 计算页面内容相对于手机容器的位置
    const pageContentRelativeToPhoneTop = pageContentRect.top - phoneContainerRect.top
    
    // 计算组件相对于手机容器的总位置
    const totalRelativeTop = pageContentRelativeToPhoneTop + relativeToPageTop
    
    // 确保标签位置基于手机容器而不是预览区域
    return {
      left: `${phoneContainerRect.right - previewAreaRect.left + 10}px`,
      top: `${phoneContainerRect.top - previewAreaRect.top + totalRelativeTop + componentRect.height / 2}px`,
      transform: 'translateY(-50%)',
      display: 'flex',
      transition: 'all 0.1s ease',
      //zIndex: editor.state.selectedComponentIndex === index ? 10000 : 9999,
      backgroundColor: editor.state.selectedComponentIndex === index ? '#409eff' : '#909399'
    }
  } catch (error) {
    console.error('标签位置计算失败:', error)
    return {
      left: 'calc(100% + 10px)',
      top: '50%',
      transform: 'translateY(-50%)',
      display: 'flex'
    }
  }
}

// 计算并更新组件标签位置（正式标签）
function updateComponentLabelPosition() {
  // 只要有组件存在就尝试显示标签
  const hasComponents = editor.state.components.length > 0
  
  if (!hasComponents) {
    return
  }
  
  // 强制设置当前活动组件
  if (editor.state.selectedComponentIndex !== -1) {
    activeComponent.value = editor.state.components[editor.state.selectedComponentIndex]
  }
  // 如果没有选中的组件，自动选中第一个
  if (editor.state.selectedComponentIndex === -1 && hasComponents) {
    editor.selectComponent(0)
  }
  
  isTempLabelShow.value = false
}


// 显示临时占位标签（组件渲染前）
function showTempLabel(targetIndex, componentName) {
  if (!previewAreaRef.value || !phoneContainerRef.value) return
  
  const previewAreaRect = previewAreaRef.value.getBoundingClientRect()
  const phoneRect = phoneContainerRef.value.getBoundingClientRect()
  
  // 临时标签默认位置：手机模拟器右侧中间
  tempLabelStyle.value = {
    left: `${phoneRect.right - previewAreaRect.left + 10}px`,
    top: `${phoneRect.top - previewAreaRect.top + phoneRect.height / 2}px`,
    transform: 'translateY(-50%)',
    display: 'flex',
    transition: 'all 0.1s ease'
  }
  
  tempLabelTargetIndex.value = targetIndex
  tempLabelComponentName.value = componentName
  isTempLabelShow.value = true
}

// 页面滚动时更新标签位置
function handlePageScroll() {
  if (editor.state.components.length > 0) {
    updateComponentLabelPosition()
  }
}

// 组件操作
function handleAddComponent(type, componentName) {
  if (!type) {
    ElMessage.error('组件类型不能为空')
    return
  }
  if (isSingletonComponent(type) && hasSingletonComponent(type)) {
    ElMessage.warning('该组件只能添加一个')
    return
  }
  
  const newIndex = editor.state.components.length
  // 1. 先显示临时标签
  showTempLabel(newIndex, componentName)
  // 2. 再添加组件
  editor.addComponent(type)
  
  // 3. 组件渲染完成后，切换到正式标签
  nextTick(() => {
    editor.selectComponent(newIndex) // 强制选中新组件
    nextTick(() => {
      updateComponentLabelPosition()
      nextTick(updateComponentLabelPosition)
    })
  })
}

function handleSelectComponent(index) {
  editor.selectComponent(index)
  activePropertyTab.value = 'component'
  
  nextTick(() => {
    updateComponentLabelPosition()
    nextTick(updateComponentLabelPosition)
  })
}

function handleUpdatePageConfig(updates) {
  editor.updatePageConfig(updates)
}

function handleUpdateComponentData(updates) {
  const index = editor.state.selectedComponentIndex
  if (index >= 0) {
    editor.updateComponent(index, { data: updates })
  }
}

function handleUpdateComponentStyles(updates) {
  const index = editor.state.selectedComponentIndex
  if (index >= 0) {
    const component = editor.state.components[index]
    // 创建新的样式对象，确保响应式更新
    const newStyles = { ...component.styles, ...updates }
    editor.updateComponent(index, { styles: newStyles })
  }
}

function handleUndo() {
  editor.undo()
  nextTick(updateComponentLabelPosition)
}

function handleRedo() {
  editor.redo()
  nextTick(updateComponentLabelPosition)
}

function handlePreview() {
  previewVisible.value = true
}

function handleSave() {
  ElMessage.success('保存成功')
}

function handleClear() {
  ElMessageBox.confirm('确定要清空所有组件吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    while (editor.state.components.length > 0) {
      editor.removeComponent(0)
    }
    // 清空时隐藏所有标签
    isTempLabelShow.value = false
    componentLabelStyle.value = {}
    activeComponent.value = null
    ElMessage.success('已清空所有组件')
  })
}

function handleImport() {
  importVisible.value = true
}

function handleExport() {
  const jsonString = editor.exportToJson()
  const blob = new Blob([jsonString], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = `diy-page-${Date.now()}.json`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
  ElMessage.success('导出成功')
}

function handleFileChange(file) {
  importFile.value = file.raw
}

function confirmImport() {
  if (!importFile.value) {
    ElMessage.error('请选择文件')
    return
  }
  const reader = new FileReader()
  reader.onload = (e) => {
    try {
      const jsonString = e.target.result
      const success = editor.importFromJson(jsonString)
      if (success) {
        ElMessage.success('导入成功')
        importVisible.value = false
        // 导入后如果有组件，自动显示第一个组件的正式标签
        if (editor.state.components.length > 0) {
          nextTick(() => {
            handleSelectComponent(0)
          })
        }
      } else {
        ElMessage.error('导入失败，请检查文件格式')
      }
    } catch (error) {
      console.error('导入错误:', error)
      ElMessage.error('导入失败，请检查文件格式')
    }
  }
  reader.readAsText(importFile.value)
}

// 拖拽相关
function handleDragStart(event, index) {
  dragIndex.value = index
  event.dataTransfer.setData('componentType', editor.state.components[index].type)
}

function handleDragOver(event) {
  event.preventDefault()
  const eventOffset = event.offsetY
  if (offsetY.value === eventOffset) return
  offsetY.value = eventOffset

  if (editor.state.components.length) {
    const container = event.currentTarget
    const children = container.children
    let insertIndex = -1

    for (let i = 0; i < children.length; i++) {
      const child = children[i]
      const childOffsetTop = child.offsetTop
      const childHeight = child.offsetHeight
      if (eventOffset < childOffsetTop + childHeight / 2) {
        insertIndex = i
        break
      }
    }
    if (insertIndex === -1) {
      insertIndex = children.length
    }
    dropPosition.value = insertIndex
  }
}

function handleDrop(event, index) {
  event.preventDefault()
  const componentType = event.dataTransfer.getData('componentType')
  const componentMeta = COMPONENT_META[componentType]
  if (isSingletonComponent(componentType) && hasSingletonComponent(componentType)) {
    ElMessage.warning('该组件只能添加一个')
    return
  }
  
  let insertIndex = index
  if (dropPosition.value >= 0) {
    insertIndex = dropPosition.value
  }
  
  // 拖拽添加时也显示临时标签
  showTempLabel(insertIndex, componentMeta?.name || '组件')
  editor.addComponent(componentType, {}, insertIndex)
  
  nextTick(() => {
    handleSelectComponent(insertIndex)
    nextTick(updateComponentLabelPosition)
  })
  
  dragIndex.value = -1
  dropPosition.value = -1
}

function handleDragEnd() {
  dragIndex.value = -1
  dropPosition.value = -1
  offsetY.value = 0
}

// 组件编辑
function handleDeleteComponent(index) {
  // 先清除组件引用
  if (componentRefs.value[index]) {
    componentRefs.value[index] = null
  }

  // 执行删除操作
  editor.removeComponent(index)
  ElMessage.success('删除成功')
  // 删除时隐藏所有标签
  isTempLabelShow.value = false
  componentLabelStyle.value = {}
  activeComponent.value = null
  // 如果还有组件，自动选中第一个
  if (editor.state.components.length > 0) {
    nextTick(() => {
      handleSelectComponent(0)
    })
  }
}

function handleMoveUpLayer(index) {
  if (index > 0) {
    editor.moveComponent(index, index - 1)
    ElMessage.success('上移成功')
    nextTick(updateComponentLabelPosition)
  }
}

function handleMoveDownLayer(index) {
  if (index < editor.state.components.length - 1) {
    editor.moveComponent(index, index + 1)
    ElMessage.success('下移成功')
    nextTick(updateComponentLabelPosition)
  }
}

// 单例组件判断
function isSingletonComponent(type) {
  return [
    COMPONENT_TYPES.TAB_BAR,
    COMPONENT_TYPES.SUSPENSION
  ].includes(type)
}

function hasSingletonComponent(type) {
  return editor.state.components.some(component => component.type === type)
}

// 返回上一页
function handlePrevious() {
  ElMessageBox.confirm('返回列表您添加或者修改的数据将会失效, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    window.history.back()
  })
}

// 监听窗口大小变化，更新标签位置
function handleResize() {
  if (editor.state.components.length > 0) {
    updateComponentLabelPosition()
  }
  // 窗口变化时，临时标签也更新位置
  if (isTempLabelShow.value && tempLabelTargetIndex.value !== -1) {
    showTempLabel(tempLabelTargetIndex.value, tempLabelComponentName.value)
  }
}

// 禁用鼠标滚轮事件
function handleWheel(e) {
  e.preventDefault()
  e.stopPropagation()
  return false
}

// 生命周期
onMounted(() => {
  pageContentRef.value?.addEventListener('scroll', handlePageScroll)
  pageContentRef.value?.addEventListener('wheel', handleWheel, { passive: false })
  window.addEventListener('resize', handleResize)
  
  // 监听组件选择变化
  watch(() => editor.state.selectedComponentIndex, () => {
    updateComponentLabelPosition()
  })
  
  // 监听组件列表变化
  watch(() => editor.state.components.length, (newLength) => {
    if (newLength > 0) {
      nextTick(updateComponentLabelPosition)
    } else {
      // 没有组件时隐藏标签
      isTempLabelShow.value = false
      componentLabelStyle.value = {}
      activeComponent.value = null
    }
  }) 
  
})

// 清理
onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  pageContentRef.value?.removeEventListener('scroll', handlePageScroll)
  pageContentRef.value?.removeEventListener('wheel', handleWheel)
})
</script>

<style lang="scss" scoped>
.txz-editor {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 125px); 
  background-color: #f5f5f5;

  .editor-toolbar {
    display: flex;
    align-items: center;
    padding: 10px 20px;
    background-color: #ffffff;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    z-index: 10;
    gap: 8px;
  }

  .editor-content {
    display: flex;
    flex: 1;
    overflow: hidden;

    .component-list {
      width: 250px;
      background-color: #ffffff;
      border-right: 1px solid #e4e7ed;
      overflow-y: auto;

      .component-category {
        margin-bottom: 15px;
      }

      .category-divider {
        position: relative;
        margin: 15px 10px 10px;
        text-align: center;

        span {
          position: relative;
          padding: 0 10px;
          background-color: #ffffff;
          color: #909399;
          font-size: 14px;
          font-weight: 500;
          z-index: 1;
        }

        &::before {
          content: '';
          position: absolute;
          top: 50%;
          left: 0;
          right: 0;
          height: 1px;
          background-color: #e4e7ed;
          transform: translateY(-50%);
        }
      }

      .component-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
        padding: 10px;

        .component-item {
          display: flex;
          flex-direction: column;
          align-items: center;
          padding: 8px 5px;
          border: 1px solid #e4e7ed;
          border-radius: 4px;
          cursor: pointer;
          transition: all 0.3s;
          font-size: 12px;

          &:hover {
            border-color: #409eff;
            background-color: #f0f9ff;
          }
        }
      }
    }

    .preview-area {
      flex: 1;
      display: flex;
      justify-content: center;
      padding: 20px;
      overflow: auto;
      position: relative;
      align-items: flex-start;
      height: 100%;
    }

    .preview-container {
      width: 100%;
      max-width: 600px;
      display: flex;
      justify-content: center;
      position: relative;
      min-height: 667px;
      padding-bottom: 20px;
    }

    .sync-scroll-container {
      min-height: 667px;
      overflow: visible;
      position: relative;
      display: flex;
      justify-content: center;
    }

    .phone-and-labels {
      display: flex;
      align-items: flex-start;
      position: relative;
    }

    .phone-container {
      width: 375px;
      height: 667px;
      background-color: #f5f5f5;
      border-radius: 30px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
      position: relative;
    }

    .phone-header {
      height: 30px;
      background-color: #000;
      position: relative;

      .phone-notch {
        width: 150px;
        height: 25px;
        background-color: #000;
        border-radius: 0 0 15px 15px;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
      }
    }

    .phone-screen {
      height: calc(100% - 60px);
      background-color: #fff;
      position: relative;
      overflow: visible;
    }

    .page-content {
      min-height: 100%;
      height: auto;
      overflow: hidden;
      scrollbar-width: none;
      position: relative;
      /* 禁用鼠标滚动但保留其他交互功能 */
      touch-action: none;
      -ms-touch-action: none;
      /* 禁用鼠标滚轮事件 */
      &::-webkit-scrollbar {
        display: none;
      }
      /* 禁用鼠标滚轮滚动 */
      overscroll-behavior: none;
    }

    .component-wrapper {
      position: relative;
      margin: 8px 0;
      padding: 8px;
      box-sizing: border-box;
      min-height: 40px;
    }

    .component-selected {
      outline: 2px dashed #409eff;
      outline-offset: 2px;
    }

    .property-panel {
      width: 300px;
      background-color: #ffffff;
      border-left: 1px solid #e4e7ed;
      overflow-y: auto;
      z-index: 10;
      position: relative;
    }
  }

  /* 组件标签样式（临时标签和正式标签共用） */
  .deles {
    position: absolute !important;
    width: 120px;
    height: 28px;
    line-height: 28px;
    background: #f5f3d4 !important;
    color: rgb(0, 0, 0) !important;
    font-size: 12px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2) !important;
    border-radius: 4px !important;
    padding: 0 10px !important;
    //z-index: 9999 !important;
    cursor: pointer !important;
    white-space: nowrap !important;
    border: none !important;
    opacity: 1 !important;
    display: flex !important;
    align-items: center;
    gap: 5px;
  }
  
  /* 移动按钮样式 */
  .move-up-btn, .move-down-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    background-color: lch(33.61% 132.29 307.01 / 0.651);
    border-radius: 2px;
    cursor: pointer;
    transition: all 0.2s;
  }
  
  .move-up-btn:hover, .move-down-btn:hover {
    background-color: rgb(255, 0, 64);
  }
  
  .move-up-btn {
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  }
  
  .move-down-btn {
    clip-path: polygon(50% 100%, 0% 0%, 100% 0%);
  }
  
  .delete-icon {
    margin-left: 2px;
    cursor: pointer;
  }
  
  .delete-icon:hover {
    color: #f56c6c;
  }
  
  /* 选中组件的删除按钮 */
  .selected-delete-btn {
    position: absolute;
    width: 24px;
    height: 24px;
    background-color: rgba(245, 108, 108, 0.85);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    //z-index: 10001;
    transition: all 0.2s;
    border: 1px solid rgba(255, 255, 255, 0.5);
  }
  
  .selected-delete-btn:hover {
    background-color: rgba(245, 108, 108, 0.95);
    transform: scale(1.1);
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);
  }
  
  .selected-delete-btn i {
    font-size: 14px;
    font-weight: bold;
  }
  
  /* 优化标签位置计算 */
  .preview-area {
    overflow: auto;
  }

  /* 左侧三角形箭头 */
  .triangle-left {
    width: 0;
    height: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-right: 6px solid #ff0116;
    margin-right: 5px;
  }

  .label-text {
    flex: 1;
  }

  .delete-icon {
    color: white;
    font-size: 14px;
  }

  /* 悬停效果 */
  .deles:hover {
    background-color: #ffc916 !important;
    
    .triangle-left {
      border-right-color: #165dff !important;
    }
  }
}
</style>